/*
 * Copyright (c) 2016. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 * www.hnapay.com
 */

package com.zf.yichat.utils.XSpay.util;

import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.X509EncodedKeySpec;

/**
 * 签名验签
 */
public class RSAAlgorithms {

    /**
     * @param publicKey 公钥HEX字符串
     * @return 返回公钥
     * @throws Exception
     */
    public static PublicKey getPublicKey(String publicKey, String ALGORITHM) throws XSpayException {
        PublicKey pubKey = null;
        try {
            byte[] encodedKey = HexStringByte.hexToByte(publicKey.getBytes());
            KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
            pubKey = keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
        } catch (InvalidKeySpecException e) {
            throw new XSpayException("公钥无效!", e);
        } catch (NoSuchAlgorithmException e) {
            throw new XSpayException("算法类型无效!", e);
        }
        return pubKey;
    }

    /**
     * @param priKey 私钥
     * @param data   要签名的数据
     * @return 签名消息
     * @throws Exception
     */
    public static byte[] sign(PrivateKey priKey, String data, String SIGN_ALGORITHM) throws XSpayException {
        try {
            Signature signet = Signature.getInstance(SIGN_ALGORITHM);
            signet.initSign(priKey);
            signet.update(data.getBytes("UTF-8"));
            return signet.sign();
        } catch (Exception e) {
            throw new XSpayException(e.getMessage());
        }
    }

    /**
     * 验证签名
     *
     * @param publicKey 公钥HEX字符串
     * @param merData   签名数据
     * @param signMsg   签名消息
     * @return 返回验证结果 true 成功 false 失败
     * @throws Exception
     */
    public static Boolean verify(String publicKey, String merData, String signMsg, String SIGN_ALGORITHM, String ALGORITHM) throws XSpayException {

        boolean bVerify = false;
        Signature signet = null;
        try {
            signet = Signature.getInstance(SIGN_ALGORITHM);
        } catch (NoSuchAlgorithmException e) {
            throw new XSpayException("算法类型不能为空!", e);
        }

        PublicKey pubKey = getPublicKey(publicKey, ALGORITHM);

        try {
            signet.initVerify(pubKey);
        } catch (InvalidKeyException e) {
            throw new XSpayException("公钥无效!", e);
        }
        try {
            signet.update(merData.getBytes("UTF-8"));
        } catch (SignatureException e) {
            throw new XSpayException("验签时符号异常!", e);
        } catch (UnsupportedEncodingException e) {
            throw new XSpayException("不支持的编码方式", e);
        }

        try {
            bVerify = signet.verify(HexStringByte.hex2byte(signMsg));
        } catch (SignatureException e) {
            throw new XSpayException("验签异常!", e);
        }
        return bVerify;
    }

}
